#import <Foundation/Foundation.h>
#import <OpenGLES/EAGL.h>
#import <OpenGLES/ES2/gl.h>
#import <OpenGLES/ES2/glext.h>
#import <OpenGLES/ES3/gl.h>
#import <OpenGLES/ES3/glext.h>
#import <QuartzCore/QuartzCore.h>
#import <CoreMedia/CoreMedia.h>
#import "MPTVBGLProgram.h"
#import <UIKit/UIKit.h>

#define MPTVBGPURotationSwapsWidthAndHeight(rotation) ((rotation) == kMPTVBGPURotateLeft || (rotation) == kMPTVBGPURotateRight || (rotation) == kMPTVBGPURotateRightFlipVertical || (rotation) == kMPTVBGPURotateRightFlipHorizontal)

#ifdef __cplusplus
extern "C" {
#endif
static inline void MPTVBGPUConfigTextureParameters(GLuint texture) {
    glBindTexture(GL_TEXTURE_2D, texture);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
}
#ifdef __cplusplus
}
#endif

typedef struct {
    GLuint texure;
    GLenum dimension;
} MPTTexture;

static const MPTTexture kMPTTextureZero = {0, 0};

static inline MPTTexture MPTTextureMake2D(GLuint textureId) {
    return (MPTTexture){textureId, GL_TEXTURE_2D};
}

typedef enum { kMPTVBGPUNoRotation, kMPTVBGPURotateLeft, kMPTVBGPURotateRight, kMPTVBGPUFlipVertical, kMPTVBGPUFlipHorizonal, kMPTVBGPURotateRightFlipVertical, kMPTVBGPURotateRightFlipHorizontal, kMPTVBGPURotate180 } MPTVBGPURotationMode;

@interface MPTVBGPUContext : NSObject

@property(readonly, nonatomic) dispatch_queue_t contextQueue;
@property(readwrite, retain, nonatomic) MPTVBGLProgram *currentShaderProgram;
@property(readonly, retain, nonatomic) EAGLContext *context;
@property (nonatomic, readonly) EAGLSharegroup *sharegroup;
@property (nonatomic ,assign) CVOpenGLESTextureCacheRef coreVideoTextureCache;
@property (nonatomic, readonly) void *pip;
@property (nonatomic, assign) BOOL isEnable;

+ (void *)contextKey;
+ (MPTVBGPUContext *)sharedImageProcessingContext;
+ (dispatch_queue_t)sharedContextQueue;
+ (void)useImageProcessingContext;
+ (void)setActiveShaderProgram:(MPTVBGLProgram *)shaderProgram;
+ (GLint)maximumTextureSizeForThisDevice;
+ (GLint)maximumTextureUnitsForThisDevice;
+ (GLint)maximumVaryingVectorsForThisDevice;
+ (BOOL)deviceSupportsOpenGLESExtension:(NSString *)extension;
+ (BOOL)deviceSupportsRedTextures;
+ (BOOL)deviceSupportsFramebufferReads;
+ (CGSize)sizeThatFitsWithinATextureForSize:(CGSize)inputSize;

//- (void)presentBufferForDisplay;
- (MPTVBGLProgram *)programForVertexShaderString:(NSString *)vertexShaderString fragmentShaderString:(NSString *)fragmentShaderString;

- (void)useSharegroup:(EAGLSharegroup *)sharegroup;

// Manage fast texture upload
+ (BOOL)supportsFastTextureUpload;

- (void)clearPrograms;

- (void)drawPlanePos:(GLuint)pos tex:(GLuint)tex;
+ (void)drawPlanePos:(GLuint)pos tex:(GLuint)tex;

@end


@protocol MPTVBGPUInput <NSObject>
- (void)newFrameReadyAtTime:(CMTime)frameTime atIndex:(NSInteger)textureIndex;
- (void)setInputTexture:(MPTTexture)newInputTexture atIndex:(NSInteger)textureIndex;
- (void)setInputSize:(CGSize)newSize atIndex:(NSInteger)textureIndex;
- (BOOL)enabled;
- (UIImage *)capture;
@end

typedef MPTVBGPUContext YXGPUContext;

